package util.bean;

import com.sun.istack.internal.NotNull;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import util.BaseUtil;

import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
import java.util.List;

/**
 * @author yangfan
 * @description propertyUtil
 * @date 2018/6/20 15:04
 **/

public class PropertyUtil extends BaseUtil {

	private final static Logger LOGGER = LoggerFactory.getLogger(PropertyUtil.class);

	private PropertyUtil() {
		LOGGER.debug("PropertyUtil");
		throw new AssertionError(getClass().getName() + " has no default instances.");
	}

	/**
	 * @param sourceObject           copy property from source object
	 * @param targetObject           copy property to target object
	 * @param sourcePropertyNameList property name will be copy
	 */
	public static void copyProperties(Object sourceObject, Object targetObject, String... sourcePropertyNameList)
			throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
		List<String> propertyNameList = Arrays.asList(sourcePropertyNameList);
		if (CollectionUtils.isNotEmpty(propertyNameList)) {
			//参数中有指定复制的属性名
			LOGGER.debug("copy property name list is {}.", propertyNameList);
			for (String propertyName : propertyNameList) {
				Object property;
				try {
					property = getProperty(sourceObject, propertyName);
					setProperty(targetObject, propertyName, property);
				} catch (NoSuchMethodException e) {
					LOGGER.error("No such copying property，property is {}!", propertyName);
					throw new NoSuchMethodException("No such copying property，property is " + propertyName);
				}
			}
		} else {
			//参数中没有制定复制属性名，进行全属性复制
			copyProperties(sourceObject, targetObject);
		}
	}

	/**
	 * @param sourceObject copy property from source object
	 * @param targetObject copy property to target object
	 * @throws IllegalAccessException
	 * @throws NoSuchMethodException
	 * @throws InvocationTargetException
	 */
	public static void copyProperties(Object sourceObject, Object targetObject)
			throws IllegalAccessException, NoSuchMethodException, InvocationTargetException {
		PropertyUtils.copyProperties(targetObject, sourceObject);
	}

	/**
	 * copy property of source object if it's not null
	 *
	 * @param sourceObject copy property from source object
	 * @param targetObject copy property to target object
	 */
	public static void copyPropertiesIfSourcePropertyIsNotNull(Object sourceObject, Object targetObject) {

	}

	/**
	 * 对象获取对应属性
	 *
	 * @param sourceObject 对象
	 * @param propertyName 属性名
	 * @return 获取的对象属性
	 * @throws IllegalAccessException
	 * @throws NoSuchMethodException
	 * @throws InvocationTargetException
	 */
	public static <T> T getProperty(Object sourceObject, String propertyName)
			throws IllegalAccessException, NoSuchMethodException, InvocationTargetException {
		return (T) PropertyUtils.getProperty(sourceObject, propertyName);
	}

	/**
	 * 设置对象属性
	 *
	 * @param targetObject 复制的对象
	 * @param propertyName 属性名
	 * @param property     属性
	 * @throws IllegalAccessException
	 * @throws NoSuchMethodException
	 * @throws InvocationTargetException
	 */
	public static <T> void setProperty(Object targetObject, String propertyName, @NotNull T property)
			throws IllegalAccessException, NoSuchMethodException, InvocationTargetException {
		PropertyUtils.setProperty(targetObject, propertyName, property);
	}

}
